package com.netease.nim.uikit.api

import android.util.Log
import com.netease.nim.uikit.R
import com.netease.nim.uikit.business.uinfo.UserInfoHelper
import com.netease.nimlib.sdk.RequestCallback
import com.netease.nimlib.sdk.friend.model.Friend
import com.netease.nimlib.sdk.msg.MessageBuilder
import com.netease.nimlib.sdk.msg.constant.SessionTypeEnum
import com.netease.nimlib.sdk.msg.model.IMMessage
import com.netease.nimlib.sdk.msg.model.SystemMessage
import com.netease.nimlib.sdk.search.model.MsgIndexRecord
import com.netease.nimlib.sdk.team.model.IMMessageFilter
import com.netease.nimlib.sdk.uinfo.model.NimUserInfo
import kotlinx.coroutines.suspendCancellableCoroutine
import www.wen.com.common.lib.extension.getString
import kotlin.coroutines.resume
import kotlin.coroutines.resumeWithException

object NIMRepository {


    suspend fun fetchUserInfo(accounts: List<String>): List<NimUserInfo> {
        return suspendCancellableCoroutine {
            NIMHelper.fetchUserInfo(accounts, object : RequestCallback<List<NimUserInfo>> {
                override fun onSuccess(param: List<NimUserInfo>) {
                    it.resume(param)
                }

                override fun onFailed(code: Int) {
                    it.cancel()
                }

                override fun onException(exception: Throwable) {
                    it.resumeWithException(exception)
                }
            })
        }
    }

    suspend fun pullMessageHistoryExType(
        sessionId: String,
        time: Long,
        uuid: String
    ): List<IMMessage> {
        return suspendCancellableCoroutine {
            NIMHelper.pullMessageHistoryExType(
                anchor = MessageBuilder.createEmptyMessage(
                    sessionId,
                    SessionTypeEnum.Team,
                    time + 1
                ),
                toTime = time,
                imMessageFilter = { message -> message.uuid != uuid },
                callback = object : RequestCallback<List<IMMessage>> {
                    override fun onSuccess(param: List<IMMessage>) {
                        it.resume(param)
                    }

                    override fun onFailed(code: Int) {
                        it.cancel()
                    }

                    override fun onException(exception: Throwable) {
                        it.resumeWithException(exception)
                    }
                })
        }
    }

    suspend fun getAddFriendMsg(offset: Int, limit: Int): List<SystemMessage> {
        return suspendCancellableCoroutine {
            NIMHelper.querySystemMessageByType(
                offset = offset,
                limit = limit,
                callback = object : RequestCallback<List<SystemMessage>> {
                    override fun onSuccess(param: List<SystemMessage>) {
                        //返回的包括回执消息
                        it.resume(param.filter { systemMessage ->
                            systemMessage.content == getString(R.string.add_friend_msg) && !NIMHelper.isInBlackList(systemMessage.fromAccount)
                        })
                    }

                    override fun onFailed(code: Int) {
                        it.cancel()
                    }

                    override fun onException(exception: Throwable) {
                        it.resumeWithException(exception)
                    }
                })
        }
    }

    suspend fun getBlackList(): List<NimUserInfo> {
        return suspendCancellableCoroutine {
            val accountList = NIMHelper.getBlackList()
            if (accountList.isEmpty()) {
                it.resume(mutableListOf())
            } else {
                NIMHelper.fetchUserInfo(
                    accountList,
                    object : RequestCallback<List<NimUserInfo>> {
                        override fun onSuccess(param: List<NimUserInfo>) {
                            it.resume(param)
                        }

                        override fun onFailed(code: Int) {
                            it.cancel()
                        }

                        override fun onException(exception: Throwable) {
                            it.resumeWithException(exception)
                        }
                    })
            }
        }
    }

    fun searchFriend(keyword: String): List<Friend> {
        if (keyword.isEmpty()) {
            return listOf()
        }
        val friendList = NIMHelper.getAllFriend()?.filter {
            UserInfoHelper.getUserTitleName(it.account, SessionTypeEnum.P2P).contains(keyword)
        }
        return friendList ?: listOf()
    }

    suspend fun searchAllMessage(keyword: String): List<MsgIndexRecord> {
        return suspendCancellableCoroutine {
            NIMHelper.searchAllMessage(keyword,
                callback = object : RequestCallback<List<MsgIndexRecord>> {
                    override fun onSuccess(param: List<MsgIndexRecord>?) {
                        it.resume(
                            param?.filter { msgIndexRecord ->
                                msgIndexRecord.sessionType == SessionTypeEnum.P2P
                            } ?: listOf()
                        )
                    }

                    override fun onFailed(code: Int) {
                        it.cancel()
                    }

                    override fun onException(exception: Throwable) {
                        it.resumeWithException(exception)
                    }
                })
        }
    }
}